package cn.iocoder.yudao.module.call.service.usercalleelist;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.call.mq.message.usercalleelistappend.UserCalleeListAppendMessage;
import cn.iocoder.yudao.module.call.mq.producer.usercalleelistappend.UserCalleeListAppendProducer;
import cn.iocoder.yudao.module.call.utils.MyStringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.module.call.controller.admin.usercalleelist.vo.*;
import cn.iocoder.yudao.module.call.dal.dataobject.usercalleelist.CallUserCalleeListDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.call.dal.mysql.usercalleelist.CallUserCalleeListMapper;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * 呼叫名单 Service 实现类
 * @author 我
 */
@Service
@Validated
@Slf4j
public class CallUserCalleeListServiceImpl implements CallUserCalleeListService {

    @Resource
    private CallUserCalleeListMapper callUserCalleeListMapper;

    @Resource
    private UserCalleeListAppendProducer userCalleeListAppendProducer;

    @Override
    public Long createList(CallUserCalleeListSaveReqVO createReqVO) {
        // 插入
        CallUserCalleeListDO list = BeanUtils.toBean(createReqVO, CallUserCalleeListDO.class);
        fillInitData(list);
        callUserCalleeListMapper.insert(list);
        // 返回
        return list.getId();
    }

    @Override
    public void updateCallListDO(CallUserCalleeListDO callUserCalleeListDO) {
        callUserCalleeListMapper.updateById(callUserCalleeListDO);
    }

    private void fillInitData(CallUserCalleeListDO list) {
        list.setStatus(0);
        list.setUserId(getLoginUserId());
    }


    @Override
    public void deleteList(Long id) {
        // 删除
        callUserCalleeListMapper.deleteById(id);
    }


    @Override
    public CallUserCalleeListDO getList(Long id) {
        return callUserCalleeListMapper.selectById(id);
    }

    @Override
    public PageResult<CallUserCalleeListDO> getListPage(CallUserCalleeListPageReqVO pageReqVO) {
        return callUserCalleeListMapper.selectPage(pageReqVO);
    }


    @Override
    public void appendNumber(String numbers) {
        List<String> numberList = MyStringUtil.split(numbers);
        batchSaveByNumberList(numberList, getLoginUserId(), 1,1);
    }

    @Override
    public void appendByFile(String path) {
        userCalleeListAppendProducer.sendUserCalleeListAppendMessage(path, 1, 1);
    }

    @Override
    public Boolean batchCreateList(CallUserCalleeListBatchSaveReqVO list) {
        list.getList().forEach(this::createList);
        return Boolean.TRUE;
    }

    @Override
    public void deleteAll(Long userId) {
        callUserCalleeListMapper.delete(new LambdaQueryWrapper<CallUserCalleeListDO>()
                .eq(CallUserCalleeListDO::getUserId, userId)
                .eq(CallUserCalleeListDO::getStatus, 0));
    }

    @Override
    public void deleteRepeat(Long loginUserId) {
        callUserCalleeListMapper.deleteRepeat(loginUserId);
    }

    /**
     * 执行从文件导入 队列使用
     *
     * @param message
     */
    @Override
    public void appendByFileExecute(UserCalleeListAppendMessage message) {
        String path = message.getPath();
        Long userId = getLoginUserId();
        Integer verify = message.getVerify();
        Integer unique = message.getUnique();
        List<String> numberList = new ArrayList<>();
        try {
            String fileType = FileTypeUtil.getType(FileUtil.file(path));
            int chunkSize = 1000;

            if (fileType.equals("xlsx")) {
                List<CallUserCalleeListNumberImportVO> list = ExcelUtils.read0(path, CallUserCalleeListNumberImportVO.class);
                for (int i = 0; i < list.size(); i += chunkSize) {
                    int endIndex = Math.min(i + chunkSize, list.size());
                    List<CallUserCalleeListNumberImportVO> saveList = list.subList(i, endIndex);
                    batchSaveByVo(saveList, userId, verify, unique);
                }
            } else {
                FileReader fileReader = new FileReader(path);
                numberList = MyStringUtil.split(fileReader.readString());
                for (int i = 0; i < numberList.size(); i += chunkSize) {
                    int endIndex = Math.min(i + chunkSize, numberList.size());
                    List<String> saveList = numberList.subList(i, endIndex);
                    batchSaveByNumberList(saveList, userId, verify, unique);
                }
            }

        } catch (Exception e) {
            throw exception(new ErrorCode(100500, e.getMessage()));
        }
    }

    private void batchSaveByNumberList(List<String> numberList, Long userId, Integer verify, Integer unique) {
        List<String> finalSaveList = new ArrayList<>();
        numberList.forEach(number -> {
            Number numberTemp = Convert.toNumber(number); //将字符串转为数字,用来排除非号码的
            if (Objects.nonNull(numberTemp)) {
                Pattern patternPhone = Pattern.compile("^0\\d{2,4}[-\\s]?\\d{7,8}$");
                if (verify.equals(0) || ValidationUtils.isMobile(number) || patternPhone.matcher(number).matches()) {
                    finalSaveList.add(number);
                }
            }
        });
        if (CollUtil.isEmpty(finalSaveList)) {
            return;
        }
        if (Objects.equals(1, unique)) {
            List<CallUserCalleeListDO> repeatDOList = callUserCalleeListMapper.selectList(
                    new LambdaQueryWrapper<CallUserCalleeListDO>()
                            .in(CallUserCalleeListDO::getNumber, finalSaveList)
            );
            if (CollUtil.isNotEmpty(repeatDOList)) {
                List<String> repeatNumList = repeatDOList.stream().map(CallUserCalleeListDO::getNumber).collect(Collectors.toList());
                finalSaveList.removeAll(repeatNumList);
            }
        }

        // 执行batchSave
        if (CollUtil.isNotEmpty(finalSaveList)) {
            List<CallUserCalleeListDO> batchSaveDOList = new ArrayList<>();
            finalSaveList.forEach(number -> {
                CallUserCalleeListDO saveDO = new CallUserCalleeListDO();
                saveDO.setNumber(number);
                saveDO.setUserId(userId);
                saveDO.setSource("import"); //固定为import
                saveDO.setSourceId("0");
                saveDO.setStatus(0);
                batchSaveDOList.add(saveDO);
            });
            callUserCalleeListMapper.insertBatch(batchSaveDOList);
        }

    }

    /**
     * 通过vo批量导入
     * @param numberVo
     * @param userId
     * @param verify
     * @param unique
     */
    private void batchSaveByVo(List<CallUserCalleeListNumberImportVO> numberVo, Long userId, Integer verify, Integer unique) {
        List<String> finalSaveList = new ArrayList<>();
        Map<String,CallUserCalleeListDO> finalVoList = new HashMap<>();
        numberVo.forEach(vo -> {
            Number numberTemp = Convert.toNumber(vo.getNumber()); //将字符串转为数字,用来排除非号码的
            if (Objects.nonNull(numberTemp)) {
                Pattern patternPhone = Pattern.compile("^0\\d{2,4}[-\\s]?\\d{7,8}$");
                if (verify.equals(0) || ValidationUtils.isMobile(vo.getNumber()) || patternPhone.matcher(vo.getNumber()).matches()) {
                    finalSaveList.add(vo.getNumber());
                    finalVoList.put(vo.getNumber(), BeanUtils.toBean(vo,CallUserCalleeListDO.class));
                }
            }
        });
        if (CollUtil.isEmpty(finalSaveList)) {
            return;
        }
        if (Objects.equals(1, unique)) {
            List<CallUserCalleeListDO> repeatDOList = callUserCalleeListMapper.selectList(
                    new LambdaQueryWrapper<CallUserCalleeListDO>()
                            .in(CallUserCalleeListDO::getNumber, finalSaveList)
            );
            if (CollUtil.isNotEmpty(repeatDOList)) {
                List<String> repeatNumList = repeatDOList.stream().map(CallUserCalleeListDO::getNumber).collect(Collectors.toList());
                finalSaveList.removeAll(repeatNumList);
            }
        }

        // 执行batchSave
        if (CollUtil.isNotEmpty(finalSaveList)) {
            List<CallUserCalleeListDO> batchSaveDOList = new ArrayList<>();
            finalSaveList.forEach(number -> {
                CallUserCalleeListDO saveDO = finalVoList.get(number);
                saveDO.setUserId(userId);
                saveDO.setSource("import"); //固定为import
                saveDO.setSourceId("0");
                saveDO.setStatus(0);
                batchSaveDOList.add(saveDO);
            });
            callUserCalleeListMapper.insertBatch(batchSaveDOList);
        }

    }


}